//
//  UIImage+Extension.swift
//  Tuhu_Shop
//
//  Created by hanSir on 2019/1/9.
//  Copyright © 2019 Tuhu. All rights reserved.
//

import UIKit

public extension UIImage {
    
    /// 通过颜色 & size 生成 image
    @objc class func image(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(size, true, UIScreen.main.scale)
        let context = UIGraphicsGetCurrentContext()
        context?.setFillColor(color.cgColor)
        context?.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height))
        let rtImg = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return rtImg
    }
    
    /// 改变图片颜色
    @objc func withRenderColor(_ color: UIColor) -> UIImage {
        if #available(iOS 13.0, *) {
            return withTintColor(color)
        } else {
            UIGraphicsBeginImageContextWithOptions(size, false, scale)
            let cx = UIGraphicsGetCurrentContext()
            cx?.setFillColor(color.cgColor)
            let bounds = CGRect(x: 0, y: 0, width: size.width, height: size.height)
            cx?.fill(bounds)
            draw(in: bounds, blendMode: .destinationIn, alpha: 1.0)
            let rt = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return rt ?? UIImage()
        }
    }
    
}

// MARK: - 图片压缩

public extension UIImage {
    
    /// 以最大图片文件大小压缩图片
    /// - param _maxDataSize: 最大图片文件尺寸，单位 KB
    ///
    /// ps: 这里是临时的图片压缩方法，因为发现一个问题不理解（image1 以 0.5 质量压缩成data1，然后用 data1 生成 image2，再用 image2 以 1 质量压缩成 data2，结果是 data2 大小比 data1 大很多）
    @objc func compress(maxDataSize: UInt) -> Data? {
        let _maxDataSize = maxDataSize * 1024
        guard var resultData = self.jpegData(compressionQuality: 1) else { return nil }
        guard resultData.count > _maxDataSize else {
            return resultData
        }
        
        // 优先压缩图片质量，优点是图片失真率低
        var minQuality: CGFloat = 0
        var maxQuality: CGFloat = 1
        var compressQuality: CGFloat = 1
        
        // 最多压缩 6 次
        for _ in 0 ... 6 {
            compressQuality = (minQuality + maxQuality) / 2.0
            guard let _resultData = self.jpegData(compressionQuality: compressQuality) else { return nil }
            resultData = _resultData
            
            // 压缩[_maxDataSize * 0.9, _maxDataSize]区间内break
            if resultData.count < Int(Double(_maxDataSize) * 0.9) {
                minQuality = compressQuality
            } else if resultData.count > _maxDataSize {
                maxQuality = compressQuality
            } else {
                break
            }
        }
        
        // 如果质量压缩未达到最大图片文件大小要求，压缩图片尺寸
        guard var resultImage = UIImage(data: resultData) else { return nil }
        var lastDataSize: Int = 0
        while resultData.count > _maxDataSize, resultData.count != lastDataSize {
            lastDataSize = resultData.count
            let ratio: CGFloat = CGFloat(_maxDataSize) / CGFloat(resultData.count)
            // 取整为了防止压缩后的图片出现白边
            let width = Int(resultImage.size.width * ratio)
            let height = Int(resultImage.size.height * ratio)
            let size = CGSize(width: width, height: height)
            UIGraphicsBeginImageContext(size)
            resultImage.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
            guard let _resultImage = UIGraphicsGetImageFromCurrentImageContext() else {
                UIGraphicsEndImageContext()
                return nil
            }
            resultImage = _resultImage
            UIGraphicsEndImageContext()
            guard let _resultData = resultImage.jpegData(compressionQuality: compressQuality) else { return nil }
            resultData = _resultData
        }
        
        return resultData
    }
    
    /// 以确定宽度等比缩放图片
    @objc func compress(limitWidth: CGFloat) -> UIImage? {
        let ratio = limitWidth / self.size.width
        let limitHeight = self.size.height * ratio
        return compress(maxPixelSize: max(limitHeight, limitWidth), scale: scale, orientation: imageOrientation)
    }
    
    /// 以确定高度等比缩放图片
    @objc func compress(limitHeight: CGFloat) -> UIImage? {
        let ratio = limitHeight / self.size.height
        let limitWidth = self.size.width * ratio
        return compress(maxPixelSize: max(limitHeight, limitWidth), scale: scale, orientation: imageOrientation)
    }
    
    
    private func compress(maxPixelSize: CGFloat, scale: CGFloat, orientation: UIImage.Orientation) -> UIImage? {
        guard let data = self.jpegData(compressionQuality: 0.9) else {
            return nil
        }
        guard let sourceRef = CGImageSourceCreateWithData(data as CFData , nil) else { return nil }
        
        let options = [kCGImageSourceCreateThumbnailFromImageAlways: kCFBooleanTrue!, kCGImageSourceThumbnailMaxPixelSize: maxPixelSize] as [CFString : Any]
        guard let imageRef = CGImageSourceCreateThumbnailAtIndex(sourceRef, 0, options as CFDictionary) else { return nil }
        let resultImage = UIImage(cgImage: imageRef, scale: scale, orientation: orientation)
        return resultImage
    }

    
}
